package debtbundler.presentation;

import java.awt.KeyboardFocusManager;
import java.awt.Window;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

/**
 * Handles uncaught exceptions in the application by logging them and displaying an 
 * error dialog.
 * <p>
 * For handling errors in modal dialogs too, this class must be registered as the AWT error handler: 
 * <code>System.setProperty("sun.awt.exception.handler", AWTExceptionHandler.class.getName());</code>
 * (source: http://stuffthathappens.com/blog/2007/10/15/one-more-note-on-uncaught-exception-handlers/).
 * Note that in later Java versions this might not work.
 * 
 * @author Anssi
 *
 */
public class AWTExceptionHandler implements Thread.UncaughtExceptionHandler {
	
	private static Logger logger = Logger.getLogger(AWTExceptionHandler.class.getName());

	/**
	 * This method is here to be able to register this class as an AWT exception handler that 
	 * catches exceptions in modal dialogs as well.
	 * 
	 * @param throwable	the throwable to handle
	 */
	public void handle(Throwable throwable) {
	    showException(Thread.currentThread(), throwable);
	}


	@Override
	public void uncaughtException(final Thread t, final Throwable e) {
        if (SwingUtilities.isEventDispatchThread()) {
            showException(t, e);
        } else {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    showException(t, e);
                }
            });
        }
    }

    private void showException(Thread thread, Throwable throwable) {
        logException(thread, throwable);

        // Locate the currently focused frame or dialog and use it as the parent
        // to prevent this dialog from being buried behind some other screen.
        KeyboardFocusManager keyboardFocusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
        Window window = keyboardFocusManager.getActiveWindow();
        JOptionPane.showMessageDialog(
        			window, 
        			String.format("Oho. Jotain meni pieleen:\n%s", throwable.getMessage()), 
        			"Virhe",
        			JOptionPane.ERROR_MESSAGE);
        // TODO a dialog with a button to exit the application
    }

    private void logException(Thread t, Throwable e) {
        logger.log(Level.SEVERE, String.format("Unexpected problem on thread %s: %s", t.getName(), e.getMessage()), e);
    }


}
